import "@site/src/languages/highlight";

# Considerations When Using TSTL

Although TypeScript To Lua (TSTL) aims to support most modern TypeScript features and compile them into Lua code, there are some language environment differences to be aware of. This article highlights some potential issues to help developers avoid pitfalls when using TSTL.

## 1. Differences Between JavaScript and Lua

Since TypeScript is based on JavaScript, some behaviors may differ when compiled to Lua. Here are a few key behavior differences:

### 1.1 Boolean Coercion

JavaScript and Lua handle boolean values differently. In Lua, certain "falsy" values in JavaScript are treated as "truthy," and TSTL follows Lua’s evaluation rules:

| TypeScript | JavaScript Behavior | Lua Behavior |
|------------|---------------------|--------------|
| `false` | `false` | `false` |
| `undefined`| `false` | `false` |
| `null` | `false` | `false` |
| `NaN` | `false` | ⚠️ `true` |
| `""` | `false` | ⚠️ `true` |
| `0` | `false` | ⚠️ `true` |
| others | `true` | `true` |

**Suggestion**: Use strict boolean expression to explicitly handle boolean values in your project.

### 1.2 Loose vs Strict Equality

In Lua, there is no distinction between `==` and `===`. TSTL treats all comparisons as strict equality (`===`), meaning `==` and `===` are equivalent in TSTL.

### 1.3 `undefined` and `null`

Lua has no direct equivalent to `null`, so TSTL converts both `undefined` and `null` to `nil`. This means that, in most cases, you can use `undefined` and `null` interchangeably. However, it is recommended to use `undefined` in TSTL code to better match Lua semantics.

### 1.4 Deleting and Checking for Table Keys

In JavaScript, object keys can have arbitrary values, including `undefined` and `null`. In Lua, removing a table key is done by assigning `nil`. Since TSTL converts both `undefined` and `null` to `nil`, this can result in keys disappearing when you attempt to read them.

**Suggestion**: If you need to use `null` or `undefined` to represent an uninitialized value in a container, use a special value like `-1` or `__TSTL_NULL`, or define a `const Null = {}` to represent it.

### 1.5 Array Length

TSTL converts TypeScript’s `.length` for arrays into Lua’s `#` operator. Due to differences in how arrays are handled in Lua, the length of arrays may differ between JavaScript and Lua. For example, setting an array index to `undefined` may alter the length in Lua, whereas it would not in JavaScript.

**Suggestion**: Avoid non-standard array operations like directly setting an index to `null` or `undefined`. Use array methods to manipulate arrays where possible.

### 1.6 Array Iteration Order

Neither JavaScript nor Lua guarantees the iteration order of object keys or array elements. In TSTL, the `for ... in` loop in JavaScript will behave differently in Lua.

**Suggestion**: If you require a consistent order, use arrays rather than objects or dictionary tables.

## 2. Other Considerations

### 2.1 Local Variable Limit

Lua imposes a limit on the number of local variables (200), whereas JavaScript/TypeScript has no such limit. If your program has a large number of local variables, it may cause runtime errors.

**Solution**: Combine multiple modules into a single table export to avoid exceeding the local variable limit.

### 2.2 Stable Sorting

Lua’s `table.sort` does not guarantee stable sorting, while JavaScript’s `Array.sort` is stable. Therefore, in TSTL, if you rely on stable sorting, you may need to implement it manually or use a third-party library.
